<script lang="ts" setup>
import {onMounted, reactive, ref, watchEffect} from 'vue'
import {ElMessage, ElMessageBox, type FormInstance, type FormRules, type UploadProps} from "element-plus";
import type {AddAndEditCourse, Course, PageCourse, PageResp} from "@/type/course.ts";
import {createCourse, deleteCourse, getCourseById, getPageCourses, updateCourse} from "@/api/course";
import {checkCoachExists} from "@/api/coach";

// 查询-下拉框+输入框数据
const input = ref('')
const select = ref('2')

// 分页-当前页码+一页多少条数据+总数据量
const currentPage = ref(1)
const pageSize = ref(6)
const total = ref(20)

// 表格数据
const parentBorder = ref(false)
const tableData = ref<Course[]>([
  {
    // 默认数据
    courseId: 1,
    courseName: '瑜伽',
    coachId: 1,
    courseDuration: 10,
    courseDescription: '暂无',
    coursePrice: 100,
    image: '暂无',
    createTime: '未知',
    updateTime: '未知'
  }
])

// 分页查询课程
const getPageCourse = async () => {
  const pageInfo: PageCourse = {
    courseId: select.value == '1' ? Number(input.value) : null,
    courseName: select.value == '2' ? input.value : '',
    coachId: select.value == '3' ? Number(input.value) : null,
    courseDescription: select.value == '4' ? input.value : '',
    page: currentPage.value,
    pageSize: pageSize.value
  }
  console.log(pageInfo)
  const result: PageResp = await getPageCourses(pageInfo)
  if (result.code == 1) {
    total.value = result.data.total
    tableData.value = result.data.records
  }
}

// 挂载时查询一次
onMounted(() => {
  console.log(currentPage.value, pageSize.value)
  getPageCourse()
})

// 监控查询变量-有变则重新查询
watchEffect(() => {
  getPageCourse()
})

// 删除课程
const delCourse = (id: number) => {
  ElMessageBox.confirm(
      '确定要删除此课程?',
      '警告',
      {
        confirmButtonText: '确认',
        cancelButtonText: '取消',
        type: 'warning',
        center: true,
      }
  )
      .then(async () => {
        try {
          const result = await deleteCourse(id); // 调用删除接口
          if (result.code === 1) {
            ElMessage({
              type: 'success',
              message: '删除成功',
            });
            await getPageCourse(); // 刷新列表
          } else {
            // 处理错误情况
            ElMessage({
              type: 'error',
              message: result.message || '删除失败，请稍后重试。',
            });
          }
        } catch (error) {
          // 捕获网络请求或其他异常
          ElMessage({
            type: 'error',
            message: '删除失败，请检查网络或稍后重试。',
          });
        }
      })
      .catch(() => {
        // 用户取消删除操作
        ElMessage({
          type: 'info',
          message: '删除取消',
        });
      });
};

// Dialog数据
const DialogVisible = ref(false)
const DialogTitle = ref('新增课程')
const addOrEdit = ref(1)  // Dialog是新增(0)还是修改(>0)即同时代表修改的课程id

// Dialog中表单数据
const DialogFormData = reactive<AddAndEditCourse>({
  courseId: -1,
  courseName: '',
  coachId: -1,
  courseDuration: -1,
  courseDescription: '',
  coursePrice: -1,
  image: '',
})

const beforeImageUpload: UploadProps['beforeUpload'] = (rawFile) => {
  if (rawFile.type == 'image/png' || rawFile.type == 'image/jpeg' || rawFile.type == 'image/gif') {
    if (rawFile.size < 4194304) {
      return true
    } else {
      ElMessage.error('上传文件必须小于 4M')
      return false
    }
  } else {
    ElMessage.error('上传文件必须是 png | img | gif')
    return false
  }
}

const handleImageSuccess: UploadProps['onSuccess'] = (response, uploadFile) => {
  DialogFormData.image = response.data
}

// 表单校验
const ruleFormRef = ref<FormInstance>()
// 规则
const checkInput = (rule: any, value: any, callback: any) => {
  if (value === '') {
    callback(new Error('不可为空,请输入...'))
  } else {
    callback()
  }
}
const checkNumber = (rule: any, value: any, callback: any) => {
  if (!Number.isInteger(value)) {
    callback(new Error('请输入数字'))
  } else {
    callback()
  }
}
const checkCoachId = async (rule: any, value: any, callback: any) => {
  try {
    const result = await checkCoachExists(value);
    if (result.code === 1) {
      if (result.data) {
        callback();
      } else {
        callback(new Error('教练不存在'));
      }
    } else {
      ElMessage.error('校验失败,请检查网络或稍后重试');
      callback(new Error('校验失败,请检查网络或稍后重试'));
    }
  } catch (error) {
    ElMessage.error('校验失败,请检查网络或稍后重试');
    callback(new Error('校验失败,请检查网络或稍后重试'));
  }
}

const rules = reactive<FormRules<AddAndEditCourse>>({
  courseName: [{validator: checkInput, trigger: 'blur'}],
  coachId: [
    {validator: checkInput, trigger: 'blur'},
    {validator: checkNumber, trigger: 'blur'},
    {validator: checkCoachId, trigger: 'blur'},
  ],
  courseDuration: [
    {validator: checkInput, trigger: 'blur'},
    {validator: checkNumber, trigger: 'blur'}
  ],
  courseDescription: [
    {validator: checkInput, trigger: 'blur'},
    {validator: checkNumber, trigger: 'blur'}
  ],
  image: []
})

// 新增课程
const addCourse = () => {
  DialogTitle.value = '新增课程'
  addOrEdit.value = 0

  // 先清空表单数据
  DialogFormData.courseName = ''
  DialogFormData.coachId = null
  DialogFormData.courseDuration = null
  DialogFormData.courseDescription = ''
  DialogFormData.coursePrice = null
  DialogFormData.image = ''

  DialogVisible.value = true
}
// 修改课程
const editCourse = async (id: number) => {
  DialogTitle.value = '修改课程'
  addOrEdit.value = id

  // 先将数据回显至表单
  // 用addOrEdit.value查询
  // 调用查询单个课程api
  const result = await getCourseById(addOrEdit.value)
  if (result.code == 1) {
    DialogFormData.courseId = result.data.courseId
    DialogFormData.courseName = result.data.courseName
    DialogFormData.coachId = result.data.coachId
    DialogFormData.courseDuration = result.data.courseDuration
    DialogFormData.courseDescription = result.data.courseDescription
    DialogFormData.coursePrice = result.data.coursePrice
    DialogFormData.image = result.data.image
  }

  DialogVisible.value = true
}
// 提交Dialog中的表单，新增或者修改
const confirm = async () => {
  if (addOrEdit.value > 0) {
    const result = await updateCourse((DialogFormData as AddAndEditCourse))
    if (result.code == 1) {
      ElMessage.success('编辑成功')
    }
  } else {
    const addFormData: Omit<AddAndEditCourse, 'courseId'> = {
      courseName: DialogFormData.courseName,
      coachId: DialogFormData.coachId,
      courseDuration: DialogFormData.courseDuration,
      courseDescription: DialogFormData.courseDescription,
      coursePrice: DialogFormData.coursePrice,
      image: DialogFormData.image,
    }
    const result = await createCourse(addFormData)
    if (result.code == 1) {
      ElMessage.success('新增成功')
    }
  }

  DialogVisible.value = false

  // 成功操作后更新表内容-再次分页查询
  await getPageCourse()
}
</script>

<template>
  <div class="course-container">
    <!--主要操作展示区-->
    <el-card>
      <div class="header-add-and-find">
        <!--左侧新增课程按钮-->
        <el-button type="primary" @click="addCourse">新增课程</el-button>
        <!--右侧查询课程按钮-->
        <el-input
            v-model="input"
            class="input-with-select"
            clearable
            placeholder="（实时搜索）请输入"
            prefix-icon="Search"
            style="max-width: 600px"
        >
          <template #prepend>
            <!--todo 该查询条件-->
            <el-select v-model="select" placeholder="Select" style="width: 115px">
              <el-option label="课程id" value="1"/>
              <el-option label="课程名" value="2"/>
              <el-option label="教练id" value="3"/>
              <el-option label="课程描述" value="4"/>
            </el-select>
          </template>
        </el-input>
      </div>
      <div class="info-main">
        <el-table :border="parentBorder" :data="tableData" max-height="445" style="width: 100%" table-layout="fixed">
          <!--详细数据展开-->
          <el-table-column type="expand">
            <template #default="props">
              <div class="detail-info" style="display: flex; justify-content: center">
                <el-card
                    style="margin: 20px; width: 75%; border-radius: 12px; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);">
                  <div style="display: flex;">
                    <!-- 左侧：图片 -->
                    <div
                        style="flex: 0 0 150px; display: flex; justify-content: center; align-items: center; padding: 20px;">
                      <el-image :src="props.row.image">
                        <template #error>
                          <div class="image-slot">
                            <el-icon>
                              <icon-picture/>
                            </el-icon>
                          </div>
                        </template>
                      </el-image>
                    </div>
                    <!-- 右侧：详细信息 -->
                    <div style="flex: 1; padding: 20px;">
                      <h2 style="margin: 0 0 10px; font-size: 24px; color: #333;">{{ props.row.courseName }}</h2>
                      <div style="display: flex; flex-wrap: wrap; gap: 10px;">
                        <p style="margin: 0; font-size: 16px; color: #666;"><strong>ID:</strong> {{
                            props.row.courseId
                          }}
                        </p>
                        <p style="margin: 0; font-size: 16px; color: #666;"><strong>教练ID:</strong> {{
                            props.row.coachId
                          }}</p>
                        <p style="margin: 0; font-size: 16px; color: #666;"><strong>课时:</strong> {{
                            props.row.courseDuration
                          }}</p>
                        <p style="margin: 0; font-size: 16px; color: #666;"><strong>价格:</strong>
                          {{ props.row.coursePrice }}</p>
                      </div>
                      <p style="margin: 10px 0 0; font-size: 16px; color: #666;"><strong>描述:</strong>
                        {{ props.row.courseDescription }}</p>
                      <div style="margin-top: 10px; font-size: 14px; color: #999;">
                        <p style="margin: 5px 0;"><strong>创建时间:</strong> {{ props.row.createTime }}</p>
                        <p style="margin: 5px 0;"><strong>更新时间:</strong> {{ props.row.updateTime }}</p>
                      </div>
                    </div>
                  </div>
                </el-card>
              </div>
            </template>


          </el-table-column>
          <!--表格展示-->
          <el-table-column align="center" label="ID" prop="courseId" width="100px"/>
          <el-table-column align="center" label="课程名" prop="courseName" width="150px"/>
          <el-table-column align="center" label="教练ID" prop="coachId" width="150px"/>
          <el-table-column align="center" label="课时" prop="courseDuration" width="150px"/>
          <el-table-column align="center" label="价格" prop="coursePrice"/>
          <el-table-column align="center" label="操作">
            <template #default="props">
              <el-button color="#E6A23C" icon="Edit" type="primary" @click="editCourse(props.row.courseId)">修改
              </el-button>
              <el-button color="#F56C6C" icon="Delete" type="primary" @click="delCourse(props.row.courseId)">删除
              </el-button>
            </template>
          </el-table-column>
        </el-table>
        <!--分页-->
        <div class="pagination-block">
          <el-pagination
              v-model:current-page="currentPage"
              v-model:page-size="pageSize"
              :background="true"
              :page-sizes="[6, 8, 10, 12, 14]"
              :total="total"
              layout="prev, pager, next, jumper, ->,sizes, total"
          />
        </div>
      </div>
    </el-card>
    <!--Dialog-->
    <el-dialog
        v-model="DialogVisible"
        :show-close="false"
        align-center
        class="add-edit-dialog"
        width="500px"
    >
      <template #header>
        <div class="dialog-title">
          {{ DialogTitle }}
        </div>
      </template>
      <!-- 表单 -->
      <el-form
          ref="ruleFormRef"
          :model="DialogFormData"
          :rules="rules"
          class="dialog-form"
          label-position="left"
          label-width="100px"
          size="default"
          status-icon
      >
        <el-form-item label="课程名" prop="courseName">
          <el-input v-model="DialogFormData.courseName" placeholder="请输入课程名"/>
        </el-form-item>
        <el-form-item label="教练ID" prop="coachId">
          <el-input v-model.number="DialogFormData.coachId" placeholder="请输入教练ID"/>
        </el-form-item>
        <el-form-item label="课时" prop="courseDuration">
          <el-input v-model.number="DialogFormData.courseDuration" placeholder="请输入课时"/>
        </el-form-item>
        <el-form-item label="价格" prop="coursePrice">
          <el-input v-model.number="DialogFormData.coursePrice" placeholder="请输入价格"/>
        </el-form-item>
        <el-form-item label="描述">
          <el-input
              v-model="DialogFormData.courseDescription"
              :rows="3"
              placeholder="请输入描述"
              type="textarea"
          />
        </el-form-item>
        <el-form-item label="图片">
          <el-upload
              :before-upload="beforeImageUpload"
              :data="{ type: 3 }"
              :on-success="handleImageSuccess"
              :show-file-list="false"
              action="http://localhost:8080/files/upload"
              class="image-uploader"
          >
            <img v-if="DialogFormData.image" :src="DialogFormData.image" class="image"/>
            <el-icon v-else class="image-uploader-icon">
              <Plus/>
            </el-icon>
          </el-upload>
        </el-form-item>
      </el-form>
      <!-- 底部按钮 -->
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="DialogVisible = false">取消</el-button>
          <el-button type="primary" @click="confirm">提交</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<style lang="scss" scoped>
.course-container {
  .header-add-and-find {
    margin-bottom: 25px;
    display: flex;
    justify-content: space-between;

    .input-with-select .el-input-group__prepend {
      background-color: var(--el-fill-color-blank);
    }
  }

  .info-main {
    .pagination-block {
      margin-top: 20px;
    }
  }

  .add-edit-dialog {
    border-radius: 12px;

    .dialog-title {
      text-align: center;
      font-weight: bold;
      font-size: 24px;
    }

    .dialog-form {
      padding: 20px;

      .image-uploader {
        display: flex;
        justify-content: center;
        align-items: center;
        border: 1px dashed #d9d9d9;
        border-radius: 6px;
        width: 100px;
        height: 100px;
        cursor: pointer;
        overflow: hidden;

        .image {
          width: 100%;
          height: 100%;
          object-fit: cover;
        }

        .image-uploader-icon {
          font-size: 24px;
          color: #8c939d;
        }

        &:hover {
          border-color: #409eff;
        }
      }
    }
  }
}
</style>

<style>
.image-uploader .el-upload {
  display: flex;
  justify-content: center;
  align-items: center;
  border: 1px dashed #d9d9d9;
  border-radius: 6px;
  width: 100px;
  height: 100px;
  cursor: pointer;
  overflow: hidden;
}

.image-uploader .el-upload:hover {
  border-color: #409eff;
}

.el-icon.image-uploader-icon {
  font-size: 24px;
  color: #8c939d;
}
</style>